import pandas as pd
import numpy as np
import math
import time

# 计算总人数和总天数
def print_stats(data):
    grouped = data['cluster'].groupby(data['usr'])
    all_user = len(grouped)
    print('总人数：', all_user)
    a = data['start'].min()
    b = data['end'].max()
    day = (b - a) / 1000 /3600 / 24
    print('总天数:', math.ceil(day))
    return all_user, math.ceil(day)

# 计算平均出行次数
def trip_per_day(data, userss, all_dayss):
    grouped = data['cluster'].groupby(data['usr'])
    length = grouped.agg(np.max).agg(np.sum)-len(grouped)
    print('总出行次数：', length)
    trip_per_day = length / userss / all_dayss
    print('人均单日出行次数：', trip_per_day)
    return length, trip_per_day


# 平均活动时间（停留时间）
def act_time_avg(data, smax):
    stime = (data['end'] - data['start']).sum()
    print('平均活动时间（小时）：', stime / smax / 1000 / 3600)
    return stime / smax / 1000/ 3600


# 平均出行时间
def times_trip_avg(data, max, userss):
    trip_time_start = data['start'].groupby(data['usr'])
    trip_time_end = data['end'].groupby(data['usr'])
    dict_trip_start = dict(list(trip_time_start))
    dict_trip_end = dict(list(trip_time_end))
    a = 0
    for key in dict_trip_start:
        time_start = dict_trip_start[key]
        time_end = dict_trip_end[key]
        temp_start = time_start[1:]
        temp_end = time_end[:len(time_end) - 1]
        a0 = np.array(list(temp_start))
        b = np.array(list(temp_end))
        a += (a0 - b).sum()
    print('平均出行时间（小时）：', a / (max - userss) / 1000 / 3600)
    return a / (max - userss) / 1000 / 3600


def get_station_longi_lati():
    path1 = './station/4g_base_station.txt'
    df = pd.read_csv(path1, header=None, sep='\s+')
    dict = {}
    for i in range(len(df)):
        list = []
        list.append(df[1][i])
        list.append(df[2][i])
        dict[i + 1] = list
    return dict


def get_station_distance(long1, lat1, long2, lat2):
    R = 6378137  # 地球半径
    lat1 = lat1 * math.pi / 180.0
    lat2 = lat2 * math.pi / 180.0
    a = lat1 - lat2
    b = (long1 - long2) * math.pi / 180.0
    sa2 = math.sin(a / 2.0)
    sb2 = math.sin(b / 2.0)
    d = 2 * R * math.asin(math.sqrt(sa2 * sa2 + math.cos(lat1) * math.cos(lat2) * sb2 * sb2))

    return d


# 根据用户的基站定位表来获取每个用户的总出行距离
def get_person_trip(ss):
    distance = 0
    # print(ss)
    for i in range(len(ss) - 1):
        ss0 = ss[i]
        ss1 = ss[i + 1]
        # print(ss0)
        long1 = intdouble[ss0][0]
        lat1 = intdouble[ss0][1]
        long2 = intdouble[ss1][0]
        lat2 = intdouble[ss1][1]
        distance += get_station_distance(long1, lat1, long2, lat2)
    return distance


def output_txt(a, b, c, d, e, f0, g, h, type=None):
    if type == 'regular':
        CLUSTER_RADIUS = 1000
        CLUSTER_TIMEINTERVAL = 120
        path = './test_cons/regular_cluster/regular_%dm_%ds.txt' % (CLUSTER_RADIUS, CLUSTER_TIMEINTERVAL)
        f = open(path, 'w')
        f.write('总人数：' + str(a))
        f.write('\n总天数:' + str(b))
        f.write('\n总出行次数：' + str(c))
        f.write('\n人均单日出行次数：' + str(d))
        f.write('\n平均活动时间（小时）：' + str(e))
        f.write('\n平均出行时间（小时）：' + str(f0))
        f.write('\n平均出行距离(公里)：' + str(g))
        f.write('\n平均活动地点数：' + str(h))
        f.close()
    if type == 'DBscan':
        radius = 500  # 距离阈值
        minT = 600  # 时间阈值
        MinPts = 40  # 核心对象邻居数
        Dpath = './test_cons/DBscan_cluster/DBscan_%dm_%ds_%d.txt' % (radius, minT, MinPts)
        Df = open(Dpath, 'w')
        Df.write('总人数：' + str(a))
        Df.write('\n总天数:' + str(b))
        Df.write('\n总出行次数：' + str(c))
        Df.write('\n人均单日出行次数：' + str(d))
        Df.write('\n平均活动时间（小时）：' + str(e))
        Df.write('\n平均出行时间（小时）：' + str(f0))
        Df.write('\n平均出行距离(公里)：' + str(g))
        Df.write('\n平均活动地点数：' + str(h))
        Df.close()


if __name__ == '__main__':
    start_time = time.time()
    # path = './data/tripgatherout1.txt'
    # path = './data/test_DB.txt'
    path = './from_DSM/DBscan_cluster_out_new.txt'
    df = pd.read_csv(path, header=None)
    df.columns = ['usr', 'cluster', 'station', 'start', 'end']
    new_df = df.groupby(df['usr'])
    #print(new_df.get_group(9338))

    # 获取总人数，总天数
    users, all_day = print_stats(df)

    # 获取总出行次数，人均单日出行次数
    max_times, avg_times = trip_per_day(df, users, all_day)

    #平均活动时间
    time_act_time_avg = act_time_avg(df, max_times)

    # 平均出行时间
    time_times_trip_avg = times_trip_avg(df, max_times, users)

    # 接下来计算日平均出行距离
    intdouble = get_station_longi_lati()
    usr_station = df['station'].groupby(df['usr'])
    station = dict(list(usr_station))
    all_trip_distance = 0

    for key in station:
        s = station[key]
        # print(s)
        list_s = list(s)
        trip_distance = get_person_trip(list_s)  # 每个用户的出行距离
        # trip_distance = get_person_trip(s)  # 每个用户的出行距离
        all_trip_distance += trip_distance
    all_trip_times = max_times - users
    print('平均出行距离(公里)：', all_trip_distance / all_trip_times / 1000)
    cons_all_trip_distance_times = all_trip_distance / all_trip_times / 1000

    # 计算平均活动点数
    # uni_station = np.unique(df['station'])
    # print(len(df['station']))
    # print(len(uni_station))
    re_station = df['station'].groupby(df['usr'])
    re_station_dict = dict(list(re_station))
    station_times = 0
    for key in re_station_dict:
        a = len(np.unique(re_station_dict[key]))
        station_times += a
    print('平均活动地点数：', station_times / users /all_day)

    # print(len(np.unique(re_station_dict[18])))
    # print(len(np.unique(df['usr'])))
    cons_station_users = station_times / users / all_day

    # 输出检测结果
    output_txt(users, all_day, max_times, avg_times, time_act_time_avg, time_times_trip_avg,
               cons_all_trip_distance_times, cons_station_users, type='DBscan')

    end_time = time.time()
    print('测试用时：', end_time - start_time)
